home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 21
/
Cream of the Crop 21 (Terry Blount) (October 1996).iso
/
os2
/
e33el2.zip
/
emacs
/
19.33
/
lisp
/
ielm.el
< prev
next >
Wrap
Lisp/Scheme
|
1996-01-20
|
18KB
|
472 lines
;;; ielm.el --- interaction mode for Emacs Lisp
;; Copyright (C) 1994 Free Software Foundation, Inc.
;; Author: David Smith <maa036@lancaster.ac.uk>
;; Created: 25 Feb 1994
;; Keywords: lisp
;; This file is part of GNU Emacs.
;; GNU Emacs is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
;;; Commentary:
;; Provides a nice interface to evaluating Emacs Lisp expressions.
;; Input is handled by the comint package, and output is passed
;; through the pretty-printer.
;; To install: copy this file to a directory in your load-path, and
;; add the following line to your .emacs file:
;;
;; (autoload 'ielm "ielm" "Start an inferior Emacs Lisp session" t)
;;
;; For completion to work, the comint.el from FSF Emacs 19.23 is
;; required. If you do not have it, or if you are running Lemacs,
;; also add the following code to your .emacs:
;;
;; (setq ielm-mode-hook
;; '(lambda nil
;; (define-key ielm-map "\t"
;; '(lambda nil (interactive) (or (ielm-tab)
;; (lisp-complete-symbol))))))
;; To start: M-x ielm. Type C-h m in the *ielm* buffer for more info.
;; The latest version is available by WWW from
;; http://mathssun5.lancs.ac.uk:2080/~maa036/elisp/dir.html
;; or by anonymous FTP from
;; /anonymous@wingra.stat.wisc.edu:pub/src/emacs-lisp/ielm.el.gz
;; or from the author: David M. Smith <maa036@lancaster.ac.uk>
;;; Code:
(require 'comint)
(require 'pp)
;;; User variables
(defvar ielm-noisy t
"*If non-nil, IELM will beep on error.")
(defvar ielm-prompt "ELISP> "
"Prompt used in IELM.")
(defvar ielm-dynamic-return t
"*Controls whether \\<ielm-map>\\[ielm-return] has intelligent behaviour in IELM.
If non-nil, \\[ielm-return] evaluates input for complete sexps, or inserts a newline
and indents for incomplete sexps. If nil, always inserts newlines.")
(defvar ielm-dynamic-multiline-inputs t
"*Force multiline inputs to start from column zero?
If non-nil, after entering the first line of an incomplete sexp, a newline
will be inserted after the prompt, moving the input to the next line.
This gives more frame width for large indented sexps, and allows functions
such as `edebug-defun' to work with such inputs.")
(defvar ielm-mode-hook nil
"*Hooks to be run when IELM (`inferior-emacs-lisp-mode') is started.")
;;; System variables
(defvar ielm-working-buffer nil
"Buffer in which IELM sexps will be evaluated.
This variable is buffer-local.")
(defvar ielm-header
(concat
"*** Welcome to IELM version "
(substring "$Revision: 1.7 $" 11 -2)
" *** Type (describe-mode) for help.\n"
"IELM has ABSOLUTELY NO WARRANTY; type (describe-no-warranty) for details.\n")
"Message to display when IELM is started.")
(defvar ielm-map nil)
(if ielm-map nil
(if (string-match "Lucid" emacs-version)
;; Lemacs
(progn
(setq ielm-map (make-sparse-keymap))
(set-keymap-parent ielm-map comint-mode-map))
;; FSF
(setq ielm-map (cons 'keymap comint-mode-map)))
(define-key ielm-map "\t" 'comint-dynamic-complete)
(define-key ielm-map "\C-m" 'ielm-return)
(define-key ielm-map "\C-j" 'ielm-send-input)
(define-key ielm-map "\e\C-x" 'eval-defun) ; for consistency with
(define-key ielm-map "\e\t" 'lisp-complete-symbol) ; lisp-interaction-mode
;; These bindings are from shared-lisp-mode-map -- can you inherit
;; from more than one keymap??
(define-key ielm-map "\e\C-q" 'indent-sexp)
(define-key ielm-map "\eq" 'lisp-fill-paragraph)
(define-key ielm-map "\177" 'backward-delete-char-untabify)
;; Some convenience bindings for setting the working buffer
(define-key ielm-map "\C-c\C-b" 'ielm-change-working-buffer)
(define-key ielm-map "\C-c\C-f" 'ielm-display-working-buffer)
(define-key ielm-map "\C-c\C-v" 'ielm-print-working-buffer))
(defvar ielm-font-lock-keywords
(list
(cons (concat "^" (regexp-quote ielm-prompt)) 'font-lock-keyword-face)
'("\\(^\\*\\*\\*[^*]+\\*\\*\\*\\)\\(.*$\\)" (1 font-lock-comment-face) (2 font-lock-reference-face)))
"Additional expressions to highlight in ielm buffers.")
;;; Completion stuff
(defun ielm-tab nil
"Possibly indent the current line as lisp code."
(interactive)
(if (or (eq (preceding-char) ?\n)
(eq (char-syntax (preceding-char)) ? ))
(progn
(ielm-indent-line)
t)))
(defun ielm-complete-symbol nil
"Complete the lisp symbol before point."
;; A wrapper for lisp-complete symbol that returns non-nil if
;; completion has occurred
(let* ((btick (buffer-modified-tick))
(cbuffer (get-buffer "*Completions*"))
(ctick (and cbuffer (buffer-modified-tick cbuffer))))
(lisp-complete-symbol)
;; completion has occurred if:
(or
;; the buffer has been modified
(not (= btick (buffer-modified-tick)))
;; a completions buffer has been modified or created
(if cbuffer
(not (= ctick (buffer-modified-tick cbuffer)))
(get-buffer "*Completions*")))))
(defun ielm-complete-filename nil
"Dynamically complete filename before point, if in a string."
(if (nth 3 (parse-partial-sexp comint-last-input-start (point)))
(comint-dynamic-complete-filename)))
(defun ielm-indent-line nil
"Indent the current line as Lisp code if it is not a prompt line."
(if (save-excursion
(beginning-of-line)
(looking-at comint-prompt-regexp)) nil
(lisp-indent-line)))
;;; Working buffer manipulation
(defun ielm-print-working-buffer nil
"Print the current IELM working buffer's name in the echo area."
(interactive)
(message "The current working buffer is: %s" (buffer-name ielm-working-buffer)))
(defun ielm-display-working-buffer nil
"Display the current IELM working buffer.
Don't forget that selecting that buffer will change its value of `point'
to its value of `window-point'!"
(interactive)
(display-buffer ielm-working-buffer)
(ielm-print-working-buffer))
(defun ielm-change-working-buffer (buf)
"Change the current IELM working buffer to BUF.
This is the buffer in which all sexps entered at the IELM prompt are
evaluated. You can achieve the same effect with a call to
`set-buffer' at the IELM prompt."
(interactive "bSet working buffer to: ")
(setq ielm-working-buffer (or (get-buffer buf) (error "No such buffer")))
(ielm-print-working-buffer))
;;; Other bindings
(defun ielm-return nil
"Newline and indent, or evaluate the sexp before the prompt.
Complete sexps are evaluated; for incomplete sexps inserts a newline
and indents. If however `ielm-dynamic-return' is nil, this always
simply inserts a newline."
(interactive)
(if ielm-dynamic-return
(let ((state
(save-excursion
(end-of-line)
(parse-partial-sexp (ielm-pm)
(point)))))
(if (and (< (car state) 1) (not (nth 3 state)))
(ielm-send-input)
(if (and ielm-dynamic-multiline-inputs
(save-excursion
(beginning-of-line)
(looking-at comint-prompt-regexp)))
(save-excursion
(goto-char (ielm-pm))
(newline 1)))
(newline-and-indent)))
(newline)))
(defun ielm-input-sender (proc input)
;; Just sets the variable ielm-input, which is in the scope of
;; `ielm-send-input's call.
(setq ielm-input input))
(defun ielm-send-input nil
"Evaluate the Emacs Lisp expression after the prompt."
(interactive)
(let ((buf (